package com.qfmy.service.impl.assistant;

import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesis;
import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesisParam;
import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesisResult;
import com.alibaba.dashscope.aigc.videosynthesis.VideoSynthesis;
import com.alibaba.dashscope.aigc.videosynthesis.VideoSynthesisParam;
import com.qfmy.config.DashScopeConfig;
import com.qfmy.config.ThreadPoolConfig;
import com.qfmy.mapper.assistant.VideoMapper;
import com.qfmy.service.assistant.VideoService;
import common.exception.BaseException;
import common.login.LoginUser;
import common.login.LoginUserHolder;
import common.result.ResultCodeEnum;
import lombok.extern.slf4j.Slf4j;
import model.entity.assistant.AiVideo;
import model.query.VideoQuery;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * @author 清风明月
 * @Package com.qfmy.service.impl.assistant
 * @date 2025/5/19
 * @description 视频生成
 */
@Slf4j
@Service
@SuppressWarnings("all")
public class VideoServiceImpl implements VideoService {

    /**
     * 注入mapper
     */
    @Autowired
    private VideoMapper videoMapper;
    /**
     * 注入dashScopeConfig
     */
    @Autowired
    private DashScopeConfig dashScopeConfig;
    /**
     * 注入redis
     */
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;


    /**
     * 文生视频
     * @param query
     * @return
     */
    @Override
    public String getVideoBytext(VideoQuery videoQuery) {
        try {
            // 创建VideoSynthesis对象，用于调用阿里百炼视频合成服务
            VideoSynthesis vs = new VideoSynthesis();

            //视频比例
            String szie = videoQuery.getWidth() + "x" + videoQuery.getHeight();
            //描述
            String prompt = "根据"  + videoQuery.getPrompt() + "生成一个视频比例为" + szie + (videoQuery.getAddMusic() ? "并且添加背景音乐" : "");
            // 构建视频合成参数
            VideoSynthesisParam param =
                    VideoSynthesisParam.builder()
                            // 指定使用的模型
                            .model(dashScopeConfig.getModelTextVideo())
                            // 设置视频描述文本
                            .prompt(prompt)
                            // 设置视频分辨率
                            .size("1280*720")
                            // 设置key
                            .apiKey(dashScopeConfig.getApiKey())
                            //灵感模式
                            .extendPrompt(videoQuery.getInspiration())
                            // 设置视频时长为5秒
                            .duration(5)
                            .build();

            // 调用阿里百炼视频合成服务，获取生成的视频URL
            String videoSrc = null;
            videoSrc = vs.call(param).getOutput().getVideoUrl();
            log.info("视频合成成功，视频地址为：{}", videoSrc);
            //异步保存图片
            String finalVideoSrc = videoSrc;
            CompletableFuture.runAsync(()->{
                // 保存生成的视频
                saveVideo(finalVideoSrc, videoQuery, "文生");
            }, ThreadPoolConfig.executorService);
            // 返回生成的视频URL
            return videoSrc;
        } catch (Exception e) {
            log.error("视频合成失败：{}", e.getMessage());
            throw  new BaseException(ResultCodeEnum.APP_VIDEO_ERROR);
        }
    }


    /**
     * 图生视频
     * @param query
     * @return
     */
    @Override
    public String getVideoByImg(VideoQuery videoQuery) {
        try {
            // 创建VideoSynthesis对象，用于调用阿里百炼视频合成服务
            VideoSynthesis vs = new VideoSynthesis();

            //描述
            String prompt = "根据"  + videoQuery.getPrompt()  + (videoQuery.getAddMusic() ? "并且添加背景音乐" : "");
            // 构建视频合成参数
            VideoSynthesisParam param =
                    VideoSynthesisParam.builder()
                            // 指定使用的模型
                            .model(dashScopeConfig.getModelImageVideo())
                            // 设置视频描述文本
                            .prompt(prompt)
                            .imgUrl(videoQuery.getImage())
                            // 设置视频分辨率
                            .size("1280*720")
                            .extendPrompt(videoQuery.getInspiration())
                            // 设置key
                            .apiKey(dashScopeConfig.getApiKey())
                            // 设置视频时长为5秒
                            .duration(5)
                            .build();

            // 调用阿里百炼视频合成服务，获取生成的视频URL
            String videoSrc = vs.call(param).getOutput().getVideoUrl();
            log.info("视频合成成功，视频地址为：{}", videoSrc);
            // 保存生成的视频
            saveVideo(videoSrc, videoQuery, "图生");
            // 返回生成的视频URL
            return videoSrc;
        } catch (Exception e) {
            log.error("视频合成失败：{}", e.getMessage());
            throw new BaseException(ResultCodeEnum.APP_VIDEO_ERROR);
        }
    }

    /**
     * 获取视频数量
     * @param time
     * @return
     */
    @Override
    public Integer getVideoCountByTime(String time) {
        //获取用户id
        Long userId = getUserId();
        Integer count = videoMapper.getVideoCountByTime(time, userId);
        return count;
    }

    /**
     * 获取所有视频
     * @return
     */
    @Override
    public List<AiVideo> getAllVideo() {
        //获取用户id
        Long userId = getUserId();
        List<AiVideo> aiVideoList = videoMapper.getAllVideo(userId);
        return aiVideoList;
    }

    /**
     * 删除视频
     * @param id
     */
    @Override
    public void deleteVideoById(Integer id) {
        //发起请求删除视频
        videoMapper.deleteVideoById(id);
    }

    /**
     * 获取视频分页
     * @param query
     * @return
     */
    @Override
    public List<AiVideo> getVideoByPage(@NotNull VideoQuery query) {
        //计算分页
        Integer start = getStart(query.getPageNum(), query.getSize());
        //设置分页
        query.setPageNum(start);
        //创建缓存key
        String key = "video:" + query.getType() + ":" + query.getPageNum();
        //从缓存中获取数据
        List<AiVideo> aiVideoList = (List<AiVideo>) redisTemplate.opsForValue().get(key);
        //判断是否为空
        if(aiVideoList != null){
            return aiVideoList;
        }
        //创建
        if(query.getType().equals("热门"))
        {
            query.setType("");
        }else if(query.getType().equals("文生视频"))
        {
            query.setType("文生");
        }else{
            query.setType("图生");
        }
        //分页查询数据
         aiVideoList = videoMapper.getVideoByPage(query);
        //将数据保存到缓存里面
        redisTemplate.opsForValue().set(key, aiVideoList,  2, TimeUnit.HOURS);
        return aiVideoList;
    }

    /**
     * 获取分页开始位置
     * @return
     */
    @Nullable
    @Contract(pure = true)
    private Integer getStart(Integer pageNum, Integer size) {
        if(pageNum == null || size == null){
            size = 20;
            pageNum = 1;
        }
        return (pageNum - 1) * size;
    }

    /**
     * 保存视频
     * @param videoSrc
     * @param videoQuery
     * @param 文生
     */
    @Transactional(rollbackFor = Exception.class)
    private void saveVideo(String videoSrc, @NotNull VideoQuery videoQuery, String type) {
        //创建视频对象
        AiVideo aiVideo = new AiVideo();
        //设置视频地址
        aiVideo.setUserId(videoQuery.getUserId());
        aiVideo.setVideoSrc(videoSrc);
        aiVideo.setType(type);
        aiVideo.setDescription(videoQuery.getPrompt());
        if(type.equals("文生"))
        {
            //生成背景图片
            String backgroundImage = getBackgroundImage(videoQuery.getPrompt());
            if(backgroundImage != null){
                aiVideo.setImage(backgroundImage);
            }
        }else {
            aiVideo.setImage(videoQuery.getImage());
        }
        //格式化时间
        String currentDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        aiVideo.setCreateTime(currentDate);
        //保存视频
        videoMapper.insert(aiVideo);
    }

    /**
     * 获取用户id
     * @return
     */
    @Nullable
    @Contract(pure = true)
    private Long getUserId() {
        LoginUser loginUser = LoginUserHolder.getLoginUser();
        if (loginUser == null) {
            throw new BaseException(ResultCodeEnum.TOKEN_INVALID);
        }
        return loginUser.getUserId();
    }

    /**
     * 生成背景图片
     */
    public String getBackgroundImage(String prompt) {
        try {
            ImageSynthesisParam param =
                    ImageSynthesisParam.builder()
                            .apiKey(dashScopeConfig.getApiKey())
                            .model(dashScopeConfig.getModelImageBackground())
                            .prompt(prompt)
                            .style("<auto>")
                            .n(1)
                            .size("1024*1024")
                            .build();

            ImageSynthesis imageSynthesis = new ImageSynthesis();
            ImageSynthesisResult result =  imageSynthesis.call(param);
            System.out.println(result.getOutput().getResults());
            return result.getOutput().getResults().get(0).get("url");
        } catch (Exception e) {
            log.error("生成背景图片失败：{}", e.getMessage());
            throw new BaseException(ResultCodeEnum.APP_IMAGE_ERROR);
        }
    }
}
